<template>
  <s-upload
    ref="upload"
    :custom-class="custom_class"
    :custom-style="custom_style"
    :name="name"
    :file-list="fileList"
    :max-count="max_count"
    :custom="custom"
    :accept="accept"
    :disabled="disabled"
    :multiple="multiple"
    :column="c_column"
    :gutter="c_gutter"
    :width="width"
    :height="height"
    :background="background"
    :radius="radius"
    :square="square"
    :max-size="maxSize"
    :deletable="deletable"
    :delete-btn-style="deleteBtnStyle"
    :show-upload="showUpload"
    :show-file-list="showFileList"
    :image-fit="imageFit"
    :video-fit="videoFit"
    :upload-style="uploadStyle"
    :upload-text="uploadText"
    :upload-text-style="uploadTextStyle"
    :upload-icon="uploadIcon"
    :upload-icon-size="uploadIconSize"
    :upload-icon-color="uploadIconColor"
    :size-type="sizeType"
    :source-type="sourceType"
    :media-type="mediaType"
    :compressed="compressed"
    :max-duration="maxDuration"
    :camera="camera"
    :preview-full-image="previewFullImage"
    :preview-full-video="false"
    :preview-full-file="previewFullFile"
    :before-read="beforeRead"
    @after-read="onAfterRead"
    @delete="onDeleteFile"
    @preview="(e) => $emit('preview', e)"
    @preview-image="(e) => $emit('preview-image', e)"
    @preview-video="onPreviewVideo"
    @preview-file="(e) => $emit('preview-file', e)"
  >
    <slot :list="fileList" :scopeParams="scopeParams" />
  </s-upload>
</template>

<script>
import SComponentMixin from '@/uni_modules/s-ui/mixins/componentMixin';
export default {
  mixins: [SComponentMixin],
  props: {
    name: {
      type: String,
      default: '',
    },
    path: {
      default: '/upload',
    },
    value: {
      type: [String, Array, Object],
      default: () => [],
    },
    objectValue: Boolean,
    uploading: {
      type: Boolean,
      default: false,
    },
    custom: Boolean,
    accept: {
      type: String,
      default: 'image',
    },
    disabled: Boolean,
    multiple: Boolean,
    column: {
      type: [Number, String],
      default: 3,
    },
    gutter: {
      type: [Number, String],
      default: 20,
    },
    width: [Number, String],
    height: [Number, String],
    background: String,
    radius: [Number, String],
    square: Boolean,
    maxSize: {
      type: Number,
      default: 5 * 1024 * 1024,
    },
    maxCount: {
      type: Number,
      default: 100,
    },
    deletable: {
      type: Boolean,
      default: true,
    },
    deleteBtnStyle: [String, Object],
    showUpload: {
      type: Boolean,
      default: true,
    },
    showFileList: {
      type: Boolean,
      default: true,
    },
    imageFit: {
      type: String,
      default: 'aspectFill',
    },
    videoFit: {
      type: String,
      default: 'cover',
    },
    uploadStyle: [String, Object],
    uploadText: String,
    uploadTextStyle: [String, Object],
    uploadIcon: {
      type: String,
      default: 'plus',
    },
    uploadIconSize: [Number, String],
    uploadIconColor: String,
    mediaType: {
      type: Array,
      default: () => ['image', 'video'],
    },
    sourceType: {
      type: Array,
      default: () => ['album', 'camera'],
    },
    sizeType: {
      type: Array,
      default: () => ['original', 'compressed'],
    },
    compressed: {
      type: Boolean,
      default: false,
    },
    maxDuration: {
      type: Number,
      default: 60,
    },
    camera: {
      type: String,
      default: 'back',
    },
    previewFullImage: {
      type: Boolean,
      default: true,
    },
    previewFullVideo: {
      type: Boolean,
      default: true,
    },
    previewFullFile: {
      type: Boolean,
      default: true,
    },
    beforeRead: Function,
  },
  data() {
    return {
      lockFileList: false,
      fileList: [],
    };
  },
  computed: {
    isList() {
      return Array.isArray(this.value);
    },
    c_column() {
      return this.isList ? this.column : 1;
    },
    c_gutter() {
      return this.isList ? this.gutter : 0;
    },
    max_count() {
      return this.isList ? this.maxCount : 1;
    },
  },
  watch: {
    value: {
      immediate: true,
      handler() {
        if (!this.lockFileList) {
          if (this.objectValue) {
            this.fileList = this.isList
              ? this.value.map(item => Object.assign({ status: 'success' }, item))
              : this.value ? [Object.assign({ status: 'success' }, this.value)] : [];
          } else {
            this.fileList = this.isList
              ? this.value.map(url => ({ url, status: 'success' }))
              : this.value ? [{ url: this.value, status: 'success' }] : [];
          }
        }
      },
    },
  },
  methods: {
    startUpload() {
      this.$refs.upload.startUpload();
    },
    clearList() {
      this.fileList = [];
      this.updateValue();
    },
    updateValue() {
      this.lockFileList = true;
      const list = this.fileList.filter(item => item.status === 'success');
      if (this.objectValue) {
        this.$emit('input', this.isList ? list : list.length ? list[0] : null);
      } else {
        const urls = list.map(item => item.url);
        this.$emit('input', this.isList ? urls : urls.length ? urls[0] : '');
      }
      this.$nextTick(() => {
        this.lockFileList = false;
      });
    },
    onAfterRead({ file }) {
      const fileList = this.fileList;
      this.$emit('update:uploading', true);
      Promise.all(([].concat(file)).map(file => {
        return new Promise(resolve => {
          const item = {
            ...file,
            status: 'uploading',
            message: '0%',
            progress: 0,
          };
          fileList.push(item);
          // uploadFile(this.path, file, progress => {
          //   item.message = `${progress}%`;
          //   item.progress = progress;
          // }).then(res => {
          //   if (res.ok) {
          item.status = 'success';
          // item.url = res.data;
          // } else {
          //   fileList.splice(fileList.indexOf(item), 1);
          // }
          resolve();
          // });
        });
      })).then(() => {
        this.updateValue();
        this.$emit('update:uploading', false);
      });
    },
    onDeleteFile({ index }) {
      this.deleteFile(index);
    },
    deleteFile(index) {
      this.fileList.splice(index, 1);
      this.updateValue();
    },
    onPreviewVideo(e) {
      this.$emit('preview-video', e);
      if (this.previewFullVideo) {
        uni.navigateTo({ url: `/pages/form/upload/play_video?url=${encodeURIComponent(e.file.url)}` });
      }
    },
  },
};
</script>
